﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ProgNetAppBlocks.Base;
using ProgNetDxComponents.Design.Editors;
using System.Drawing.Design;
using ProgNetComponents;
using ProgNetComponents.Design.Editors;
using ProgNetComponents.Data.Query;
using ProgNetDxComponents.ExtenderProviders.Language;
using ProgNetComponents.Data;

namespace ProgNetAppBlocks.Forms
{
    public partial class ProgNetBaseDbForm : ProgNetForm
    {
        #region fields
        protected virtual object CurrentRecordId
        {
            get;
            set;
        }
        protected virtual bool IsSingleQuery
        {
            get { throw new NotImplementedException("IsSingleQuery"); }
        }
        
        private SelectData _SelectData;
        protected SelectData SelectData
        {
            get
            {
                if (_SelectData == null && this.IsAppRunning())
                {
                    _SelectData = SelectDataCache.GetData(SelectDataName);
                    Manager.AddSelectData(DataSource, _SelectData, IsSingleQuery);
                }
                return _SelectData;
            }
        }
        protected DataManager Manager
        {
            get
            {
                if (IsSingleQuery)
                    return SelectData.SingleRecordManager;
                return SelectData.MultiRecordManager;
            }
        }
        protected virtual string FormText
        {
            get { return ProgNetLanguage.sGetStringDefault(SelectDataName, SelectDataName); }
        }
        protected List<string> Errors = new List<string>();
        #endregion

        #region Properties
        [Category(Categories.ProgNetSettings)]
        public DataSet DataSource
        {
            get;
            set;
        }

        [Category(Categories.ProgNetSettings),
        Editor(typeof(SelectDataNameEditor), typeof(UITypeEditor))]
        public string SelectDataName
        {
            get;
            set;
        }

        [Category(Categories.ProgNetSettings)]
        public bool ReopenAfterSave
        {
            get;
            set;
        }

        [Category(Categories.ProgNetSettings)]
        public bool OpenOnLoad
        {
            get;
            set;
        }

        [Category(Categories.ProgNetSettings)]
        public bool AllowChangeText
        {
            get;
            set;
        }

        #endregion

        public ProgNetBaseDbForm()
        {
            InitializeComponent();
        }

        #region Protected Virtual Methods
        protected virtual void FinishEdit()
        {
            this.FinishEditBindings();
        }

        /// <summary>
        /// When overriden should add errors to Errors list
        /// </summary>
        /// <returns></returns>
        protected virtual void ValidateAll()
        {

        }

        protected virtual void ClearValidation()
        {
            Errors.Clear();
        }
        
        protected virtual void PreInitForm()
        {
        }
        #endregion
        #region protected methods
        protected void AddError(string error)
        {
            if (!Errors.Contains(error))
                Errors.Add(error);
        }

        protected bool DoValidate()
        {
            ClearValidation();
            ValidateAll();
            return Errors.Count == 0;
        }
        #endregion

        #region Menu Click
        private void bbiOdswiez_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            RefreshEntry();
        }

        private void bbiOtworz_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            DoOpenRecord();
        }

        private void bbiEdytuj_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ToggleEdit();
        }

        private void bbiZapisz_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            DoSave();
        }

        private void bbiUsun_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Delete();
        }

        #region Menu Click Handlers
        protected virtual bool RefreshEntry()
        {
            bool result = true;
            FinishEdit();
            if (changeDetercorProvider1.HasChanges)
            {
                DialogResult dlg = this.ShowDxYNCQuestionDialog("Zapisać zmiany?");
                if (dlg == System.Windows.Forms.DialogResult.Yes)
                {
                    result = DoSave();
                }
                else if (dlg == System.Windows.Forms.DialogResult.No)
                {
                    modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.Read;
                    result = true;
                }
                else
                    result = false;
            }
            if (result)
                DoOpenEntry();
            return result;
        }
        protected virtual void DoOpenRecord()
        {
            bool result = true;
            if (changeDetercorProvider1.HasChanges)
            {
                DialogResult dlg = this.ShowDxYNCQuestionDialog("Zapisać zmiany?");
                if (dlg == System.Windows.Forms.DialogResult.Yes)
                {
                    result = DoSave();
                }
                else if (dlg == System.Windows.Forms.DialogResult.No)
                {
                    result = true;
                }
                else
                    result = false;
            }

            if (result)
                OpenRecord();
        }
        protected virtual bool OpenRecord()
        {
            throw new NotImplementedException("OpenRecord");
        }
        protected virtual bool ToggleEdit()
        {
            bool result = true;
           
            if (modeProvider1.CurrentMode == ProgNetDxComponents.ExtenderProviders.FormMode.Read)
            {
                modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.Edit;
            }
            else
            {
                if (!changeDetercorProvider1.HasChanges)
                     FinishEdit();
                if (changeDetercorProvider1.HasChanges)
                {
                    DialogResult dlg = this.ShowDxYNCQuestionDialog("Zapisać zmiany?");
                    if (dlg == System.Windows.Forms.DialogResult.Yes)
                    {
                        if (DoSave())
                            modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.Read;
                        result = false;
                    }
                    else if (dlg == System.Windows.Forms.DialogResult.No)
                    {
                        DataSource.RejectChanges();
                        changeDetercorProvider1.ResetAll();
                        result = true;
                        modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.Read;
                    }
                    else
                        result = false;
                }
                else
                    modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.Read;
            }
            return result;
        }
        protected virtual bool DoSave()
        {
            bool result = true;
            FinishEdit();
            if (DoValidate())
            {
                if (Save())
                {
                    modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.Read;
                    changeDetercorProvider1.ResetAll();
                    UpdateBrowserState();
                    DataSource.AcceptChanges();
                    if (ReopenAfterSave)
                        DoOpenEntry();
                }
                else
                {
                    this.ShowDxErrorDialog("Błąd zapisu!");
                    result = false;
                }
            }
            else
            {
                this.ShowDxErrorDialog(Errors.AsSingleString());
                result = false;
            }
            return result;
        }
        protected virtual bool Save()
        {
            bool result = true;
            result = Manager.UpdateDataSet(DataSource);
            if (!result)
            {
                if(!Manager.GetAutoLogExceptions)
                Manager.LastException.Log();
            }
            return result;
        }
        protected virtual bool Delete()
        {
            throw new NotImplementedException("Delete");
        }
        protected virtual bool OpenEntry()
        {
            throw new NotImplementedException("OpenEntry");
        }
        protected virtual void DoOpenEntry()
        {
            if (OpenEntry())
            {
                changeDetercorProvider1.ResetAll();
                this.Text = FormText;
            }
            else
            {
                this.ShowDxErrorDialog("Błąd otwarcia rekordu.");
                modeProvider1.CurrentMode = ProgNetDxComponents.ExtenderProviders.FormMode.View;
            }
        }

        protected virtual void UpdateBrowserState()
        {
            ProgNetDxComponents.ExtenderProviders.Browsers.BrowserCache.DataGrabber.SetLastUpdateTime(DataSource);
        }

        #endregion

        #endregion
        private void ProgNetBaseDbForm_Load(object sender, EventArgs e)
        {
            if (this.IsAppRunning())
            {
                PreInitForm();
                if (OpenOnLoad)
                {
                    DoOpenEntry();
                }
            }
        }
        protected virtual void changeDetercorProvider1_ContextChanged(object sender, EventArgs e)
        {
            
        }

        protected virtual void ModeSettings_CustomGetControlModes(object sender, ProgNetDxComponents.ExtenderProviders.Settings.ModeSettingsEventArgs e)
        {
            if (sender == bbiZapisz)
                e.IsReadOnly = !changeDetercorProvider1.HasChanges;
        }

        protected virtual void changeDetercorProvider1_HasChangesChanged(object sender, EventArgs e)
        {
            if (this.IsAppRunning())
            {
                if (AllowChangeText)
                {
                    modeProvider1.RefreshObjects(bbiZapisz);
                    if (changeDetercorProvider1.HasChanges)
                    {
                        if (!this.Text.EndsWith(" *"))
                        {
                            this.Text += " *";
                        }
                    }
                    else
                    {
                        if (this.Text.EndsWith(" *"))
                        {
                            this.Text = this.Text.Substring(0, this.Text.Length - 2);
                        }
                    }
                }
            }
        }

    }
}
